﻿#pragma once
#include "callback.h"
#include "config.h"
#include "hid_interface.h"
#include "threadpool.h"
#include <atomic>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

/**
 * 任务状态管理
 */
enum State {
  STARTED, // 开始
  PAUSE,   // 暂停
  PAUSED,  // 已暂停
  RESUMED, // 恢复
  CANCEL,
  STOP,   // 停止
  STOPPED // 已停止
};

/**
 * 随机文件类型
 */
enum FileExtension { MP4_LIVE, BINARY };

/**
 * HID编码器
 * @brief The hid_encoder class
 */
class hid_encoder {

private:
  std::atomic<bool> isRunning = false;
  std::atomic<bool> interrupt = false;
  long pos = 0;
  bool mRandomTaskRunning = false;
  State state = STOPPED;
  bool flag = false;
  int index = 0;
  int mRetransmitPacket = 5;

  // 内部防止资源竞争用到的锁
  std::mutex g_Mutex;
  // 用以外部函数操作的锁
  std::mutex m_Mutex_Var;

  // 停止发送数据弱应用对象
  std::weak_ptr<OnHIDStopDataListener> stopListenerPtr;

  // hid_engine 实例的弱引用
  std::shared_ptr<hid_interface> hidInterface;
  std::unique_ptr<ThreadPool> threadPool;
  std::shared_ptr<config> cfg;

public:
  hid_encoder(std::shared_ptr<hid_interface> _hid_interface,
              std::shared_ptr<config> cfg);

  ~hid_encoder();

  // 异步写文件带回调
  void writeFile(const std::string &filePath, const char *tag, int tagSize,
                 std::weak_ptr<OnHIDWriteListener> writeListener);

  // 异步写文件不带回调，对于文件只有异步写的方法
  void writeFile(const std::string &filePath, const char *tag, int tagSize);

  // 异步写数据
  void writeData(const char *data, int size, const char *tag, int tagSize,
                 char cmd, std::weak_ptr<OnHIDWriteListener> writeListener);

  // 同步写数据
  bool writeDataSync(const char *data, int size, const char *tag, int tagSize,
                     char cmd);

  // 写随机文件
  void writeRandomFile(const std::string &filePath, int fileExtension,
                       std::weak_ptr<OnHIDWriteRandomFileListener> l);

  // 取消随机写文件
  void cancelRandomFile();

  // 暂停任务
  void pause();

  // 恢复任务
  void resume();

  // 停止写随机文件
  void stopRandomFile();

  // 停止
  bool stop(std::weak_ptr<OnHIDStopDataListener> l);

  // 取消任务
  void cancel();

  bool isRun() const;

private:
  void release();

  int write(char *data, int length);
};
